package com.eolcum.evo.service;

import java.io.IOException;
import java.util.List;
import java.util.Set;

import com.eolcum.evo.persistence.Apartment;
import com.eolcum.evo.persistence.DataBaseHelper;
import com.eolcum.evo.persistence.RTCLog;
import com.eolcum.evo.thread.BroadcastManager;
import com.eolcum.evo.thread.CommunicationManager;
import com.eolcum.evo.thread.HomeController;
import com.eolcum.evo.thread.SerialCommunicationManager;
import com.eolcum.evo.util.Constants;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.database.SQLException;
import android.hardware.usb.UsbManager;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

@SuppressLint("InlinedApi")
public class EvoService extends Service {
	private static final String TAG = "EvoService";
	private Apartment apartment;
	private DataBaseHelper myDbHelper;

	/** Called when the activity is first created. */
	@Override
	public void onCreate() {
		super.onCreate();
		Log.d(TAG, "Service created.");
//		getApplicationContext().startService(new Intent(getApplicationContext(), EvoCommunicationService.class));
		myDbHelper = new DataBaseHelper(getApplicationContext());

		try {
			myDbHelper.createDataBase();
		} catch (IOException ioe) {
			throw new Error("Unable to create database");
		}

		try {
			myDbHelper.openDataBase();
		} catch (SQLException sqle) {
			throw sqle;
		}

		apartment = myDbHelper.getApartment();
		while (apartment == null)
			apartment = myDbHelper.getApartment();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.d(TAG, "Service started.");

		Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
		Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);
		boolean alreadyRunning = false;
		for (int i = 0; i < threadArray.length; i++) {
			if (threadArray[i].getName().equals(Constants.HOME_CONT_THREAD_NAME_PREFIX + apartment.getId())) {
				Log.i("MainActivity", "EVO_" + apartment.getId() + " is already running!");
				alreadyRunning = true;
			}
		}
		
		if (!alreadyRunning)
			startHomeController(myDbHelper);

		return super.onStartCommand(intent, flags, startId);
	}

	private void startHomeController(DataBaseHelper myDbHelper) {
		HomeController hc;
		hc = new HomeController();
		hc.setApartment(apartment);
		hc.setDbHelper(myDbHelper);
		hc.setContext(getApplicationContext());
		new Thread(hc, Constants.HOME_CONT_THREAD_NAME_PREFIX + apartment.getId()).start();

		BroadcastManager bm = new BroadcastManager();
		bm.setApartment(apartment);
		bm.setContext(getApplicationContext());
		new Thread(bm, Constants.BROADCAST_MANAGER_THREAD_NAME_PREFIX + "1").start();

		
		UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
		SerialCommunicationManager scm = new SerialCommunicationManager();
		scm.setUsbManager(usbManager);
		scm.setApartment(apartment);
		scm.setContext(getApplicationContext());
		new Thread(scm, Constants.SERIAL_COMM_THREAD_NAME_PREFIX).start();
		
		CommunicationManager cm = new CommunicationManager();
		cm.setApartment(apartment);
		cm.setContext(getApplicationContext());
		cm.setDbHelper(myDbHelper);
		new Thread(cm, Constants.COMM_MNGR_THREAD_NAME_PREFIX).start();
	}

	IBinder mBinder = new EvoServiceLocalBinder();

	@Override
	public IBinder onBind(Intent intent) {

		return mBinder;
	}

	public class EvoServiceLocalBinder extends Binder {
		public EvoService getServerInstance() {
			return EvoService.this;
		}
	}

	public Apartment getApartment() {
		return apartment;
	}
	
	public List<RTCLog> getLog(int roomId) {
		return myDbHelper.getLogRTCList(roomId);
	}
}